/*
 * Copyright (c) 2020-2099 the original author or authors. All rights reserve.
 */
package org.tianyun.cloud.config.console;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.tianyun.cloud.config.console.client.ConsoleConfigServer;
import org.tianyun.cloud.config.console.client.response.ConfigRequest;

/**
 * 服务启动完成后，上报配置到控制台
 *
 * @author ebert_chan
 */
public class ConsolePushConfigListenner implements SmartApplicationListener {

    private static final Logger log = LoggerFactory.getLogger(ConsolePushConfigListenner.class);

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationReadyEvent) {
            postConfig();
            return;
        }

        if (event instanceof RefreshScopeRefreshedEvent) {
            // 配置刷新事件只需要处理RefreshScopeRefreshedEvent
            // 调用链：
            // ①：EnvironmentChangeEvent->SmartRefresher.addChangedKeys
            // ②：RefreshScope.refreshAll()->RefreshScopeRefreshedEvent->SmartScope.refresh(keys)->SmartScopeRefreshedEvent->RefreshScopeRefreshedEvent
            RefreshScopeRefreshedEvent refreshScopeRefreshedEvent = (RefreshScopeRefreshedEvent) event;
            if (!RefreshScopeRefreshedEvent.DEFAULT_NAME.equals(refreshScopeRefreshedEvent.getName())) {
                return;
            }

            /*ConsoleManager.getAllComponents().keySet().forEach(beanName -> {
                // 重新获取一次，让对象重新创建
                AppContext.getBean(beanName);
            });*/

            postConfig();
        }
    }

    private void postConfig() {
        ConfigRequest config = ConsoleManager.buildConfig();
        if (config == null) {
            return;
        }
        new Thread(() -> {
            try {
                ConsoleConfigServer.pushConfig(config);
            } catch (Exception e) {
                log.error("Failed to push configuration from console.", e);
            }
        }).start();
    }

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return ApplicationReadyEvent.class.isAssignableFrom(eventType) || RefreshScopeRefreshedEvent.class.isAssignableFrom(eventType);
    }

}
